package com.youdianstar.app.common.network

import okhttp3.Cookie
import okhttp3.CookieJar
import okhttp3.HttpUrl
import com.youdianstar.app.common.util.CacheUtil
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import java.util.concurrent.ConcurrentHashMap

class LocalCookieJar : CookieJar {
    companion object {
        @Volatile
        private var INSTANCE: LocalCookieJar? = null
        
        fun getInstance(): LocalCookieJar {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: LocalCookieJar().also { INSTANCE = it }
            }
        }
    }
    
    //cookie的本地化存储 - 使用持久化存储而不是内存
    private val cache = ConcurrentHashMap<String, MutableList<Cookie>>()
    private val gson = Gson()
    
    init {
        // 从缓存中恢复cookie
        loadCookiesFromCache()
    }

    override fun loadForRequest(url: HttpUrl): List<Cookie> {
        val validCookies = mutableListOf<Cookie>()
        val invalidCookies = mutableListOf<Cookie>()
        
        // 获取该域名下的所有cookie
        val domainCookies = cache[url.host] ?: return emptyList()
        
        for (cookie in domainCookies) {
            if (cookie.expiresAt < System.currentTimeMillis()) {
                // 判断是否过期
                invalidCookies.add(cookie)
            } else if (cookie.matches(url)) {
                // 匹配Cookie对应url
                validCookies.add(cookie)
            }
        }
        
        // 移除过期的Cookie
        domainCookies.removeAll(invalidCookies)
        
        // 如果该域名下没有有效cookie了，移除该域名
        if (domainCookies.isEmpty()) {
            cache.remove(url.host)
        }
        
        return validCookies
    }

    override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
        if (cookies.isNotEmpty()) {
            val domainCookies = cache.getOrPut(url.host) { mutableListOf() }
            
            // 移除同名的cookie（如果有的话）
            cookies.forEach { newCookie ->
                domainCookies.removeAll { it.name == newCookie.name }
                domainCookies.add(newCookie)
            }
            
            // 保存cookie到持久化存储
            saveCookiesToCache()
        }
    }
    
    /**
     * 从缓存中加载cookie
     */
    private fun loadCookiesFromCache() {
        try {
            val cookieJson = CacheUtil.instance.getStringValue("cookies", "")
            if (cookieJson.isNotEmpty()) {
                val type = object : TypeToken<Map<String, List<SerializableCookie>>>() {}.type
                val savedCookies: Map<String, List<SerializableCookie>> = gson.fromJson(cookieJson, type)
                
                savedCookies.forEach { (domain, serializableCookies) ->
                    val domainCookies = mutableListOf<Cookie>()
                    serializableCookies.forEach { serializableCookie ->
                        try {
                            val cookie = SerializableCookie.toCookie(serializableCookie)
                            // 检查cookie是否过期
                            if (cookie.expiresAt >= System.currentTimeMillis()) {
                                domainCookies.add(cookie)
                            }
                        } catch (e: Exception) {
                            // 忽略无效的cookie
                        }
                    }
                    if (domainCookies.isNotEmpty()) {
                        cache[domain] = domainCookies
                    }
                }
            }
        } catch (e: Exception) {
            // 忽略异常，清空缓存
            cache.clear()
        }
    }
    
    /**
     * 保存cookie到缓存
     */
    private fun saveCookiesToCache() {
        try {
            val serializableCookies = mutableMapOf<String, List<SerializableCookie>>()
            
            cache.forEach { (domain, cookies) ->
                val validCookies = cookies.filter { it.expiresAt >= System.currentTimeMillis() }
                if (validCookies.isNotEmpty()) {
                    serializableCookies[domain] = validCookies.map { SerializableCookie.fromCookie(it) }
                }
            }
            
            val cookieJson = gson.toJson(serializableCookies)
            CacheUtil.instance.setStringValue("cookies", cookieJson)
        } catch (e: Exception) {
            // 忽略异常
        }
    }
    
    /**
     * 清理所有cookie
     */
    fun clearCookies() {
        cache.clear()
        CacheUtil.instance.setStringValue("cookies", "")
    }
    
    /**
     * 清理指定域名的cookie
     */
    fun clearCookiesForDomain(domain: String) {
        cache.remove(domain)
        saveCookiesToCache()
    }

}